"""
用户认证路由模块

处理用户的认证相关功能，包括：
1. 首页路由（根据用户类型重定向到不同页面）
2. 用户登录
3. 用户注册
4. 用户登出
5. 头像上传
"""

from flask import Blueprint, render_template, request, redirect, url_for, flash, jsonify, current_app
from flask_login import login_user, logout_user, login_required, current_user
from werkzeug.security import generate_password_hash, check_password_hash
from ..models.database import db
from ..models.models import Teacher, Student, Registration, Course, Class, Grade
from ..auth.forms import LoginForm, RegistrationForm
from werkzeug.utils import secure_filename
import os

# 创建蓝图对象，用于组织认证相关的路由
bp = Blueprint('auth', __name__)

@bp.route('/')
def index():
    """
    首页路由
    
    根据用户的登录状态和类型重定向到不同的页面：
    - 已登录的教师 -> 教师首页
    - 已登录的学生 -> 学生首页
    - 未登录用户 -> 登录页面
    
    Returns:
        str: 渲染后的HTML页面
    """
    if current_user.is_authenticated:
        if isinstance(current_user, Teacher):
            return render_template('teacher/index.html')
        else:
            return render_template('student/index.html')
    return render_template('index.html')

@bp.route('/login', methods=['GET', 'POST'])
def login():
    """
    用户登录路由
    
    处理用户的登录请求：
    1. GET请求：显示登录表单
    2. POST请求：验证用户凭据并登录
    
    登录流程：
    1. 验证表单数据
    2. 查找用户注册记录
    3. 验证密码
    4. 根据用户类型（教师/学生）加载用户对象
    5. 使用Flask-Login登录用户
    6. 重定向到对应的首页
    
    Returns:
        str: 登录表单页面或重定向到首页
    """
    form = LoginForm()
    
    if form.validate_on_submit():
        user_id = form.username.data
        password = form.password.data
        
        # 查找注册记录
        registration = Registration.query.filter_by(user_id=user_id).first()
        
        if registration:
            password_check = registration.check_password(password)
            
            if password_check:
                # 根据用户类型加载用户
                if registration.user_type == 'teacher':
                    teacher = Teacher.query.get(user_id)
                    if teacher:
                        login_user(teacher)
                        return redirect(url_for('teacher_auth.index'))
                else:  # student
                    # 直接使用注册信息登录学生
                    student = Student.query.filter_by(student_number=user_id).first()
                    if student:
                        login_user(student)
                        return redirect(url_for('student.index'))
        
        flash('工号/学号或密码错误')
        return redirect(url_for('auth.login'))
    
    return render_template('auth/login.html', form=form)

@bp.route('/register', methods=['GET', 'POST'])
def register():
    """
    用户注册路由
    
    处理用户的注册请求：
    1. GET请求：显示注册表单
    2. POST请求：处理注册数据
    
    注册流程：
    1. 验证表单数据
    2. 检查用户名和工号/学号是否已存在
    3. 验证工号/学号在对应表中是否存在
    4. 创建新用户注册记录
    5. 加密存储密码
    6. 保存到数据库
    
    Returns:
        str: 注册表单页面或重定向到登录页面
    """
    form = RegistrationForm()
    if form.validate_on_submit():
        user_type = form.user_type.data
        user_id = form.user_id.data
        username = form.username.data
        password = form.password.data
        email = form.email.data
        phone = form.phone.data

        try:
            # 检查用户名是否已存在
            existing_user = Registration.query.filter_by(username=username).first()
            if existing_user:
                flash('用户名已存在，请更换其他用户名')
                return redirect(url_for('auth.register'))

            # 检查工号/学号是否已存在
            existing_id = Registration.query.filter_by(user_id=user_id).first()
            if existing_id:
                flash('该工号/学号已被注册，请直接登录')
                return redirect(url_for('auth.register'))
            
            # 根据用户类型检查工号/学号是否在对应的表中存在
            if user_type == 'teacher':
                teacher = Teacher.query.filter_by(teacher_id=user_id).first()
                if not teacher:
                    flash('该工号在教师信息中不存在，请确认工号是否正确')
                    return redirect(url_for('auth.register'))
            else:  # student
                student = Student.query.filter_by(student_number=user_id).first()
                if not student:
                    flash('该学号在学生信息中不存在，请确认学号是否正确')
                    return redirect(url_for('auth.register'))
            
            # 创建新用户
            new_user = Registration(
                user_type=user_type,
                user_id=user_id,
                username=username,
                email=email,
                phone=phone
            )
            new_user.set_password(password)
            
            db.session.add(new_user)
            db.session.commit()
            
            flash('注册成功，请登录')
            return redirect(url_for('auth.login'))
            
        except Exception as e:
            db.session.rollback()
            flash('注册失败，请检查所有信息是否正确')
            return redirect(url_for('auth.register'))
    
    # 如果表单验证失败，显示具体的错误信息
    if form.errors:
        for field, errors in form.errors.items():
            for error in errors:
                flash(f'{getattr(form, field).label.text}: {error}')
    
    return render_template('auth/register.html', form=form)

@bp.route('/logout')
@login_required
def logout():
    """
    用户登出路由
    
    处理用户的登出请求：
    1. 使用Flask-Login登出当前用户
    2. 重定向到登录页面
    
    Returns:
        str: 重定向到登录页面
    """
    logout_user()
    return redirect(url_for('auth.login'))

@bp.route('/api/upload-avatar', methods=['POST'])
@login_required
def upload_avatar():
    """
    头像上传API
    
    处理用户头像上传请求：
    1. 验证上传文件
    2. 生成安全的文件名
    3. 保存文件到服务器
    4. 更新数据库中的头像路径
    
    文件处理：
    - 文件名格式：{user_type}_{user_id}.{ext}
    - 存储位置：static/uploads/avatars/
    - 支持的格式：由werkzeug.utils.secure_filename决定
    
    Returns:
        JSON: 上传结果，包含成功状态、消息和头像URL
    """
    if 'avatar' not in request.files:
        return jsonify({'success': False, 'message': '没有文件'}), 400

    file = request.files['avatar']
    if file.filename == '':
        return jsonify({'success': False, 'message': '没有选择文件'}), 400

    if file:
        try:
            # 获取注册信息
            registration = Registration.query.filter_by(
                user_type='teacher' if isinstance(current_user, Teacher) else 'student',
                user_id=str(current_user.teacher_id if isinstance(current_user, Teacher) else current_user.student_number)
            ).first()

            if not registration:
                return jsonify({'success': False, 'message': '未找到注册信息'}), 404

            # 确保文件名安全
            filename = secure_filename(file.filename)
            # 生成唯一的文件名
            ext = filename.rsplit('.', 1)[1].lower()
            user_type = 'teacher' if isinstance(current_user, Teacher) else 'student'
            user_id = current_user.teacher_id if isinstance(current_user, Teacher) else current_user.student_number
            new_filename = f"{user_type}_{user_id}.{ext}"
            
            # 确保上传目录存在
            upload_folder = os.path.join(current_app.static_folder, 'uploads', 'avatars')
            os.makedirs(upload_folder, exist_ok=True)
            
            # 保存文件
            file_path = os.path.join(upload_folder, new_filename)
            file.save(file_path)
            
            # 更新注册表中的头像路径
            avatar_path = f'/static/uploads/avatars/{new_filename}'
            
            # 更新数据库
            try:
                registration.avatar = avatar_path
                db.session.commit()
            except Exception as db_error:
                db.session.rollback()
                raise db_error
            
            return jsonify({
                'success': True,
                'message': '头像上传成功',
                'avatar_url': avatar_path
            })
        except Exception as e:
            db.session.rollback()
            return jsonify({'success': False, 'message': str(e)}), 400

    return jsonify({'success': False, 'message': '上传失败'}), 400 